import { useMemo } from 'react';
import { isEqual as _isEqual } from 'lodash';
import type { Size, Direction } from './index';

const map: any = {};
const cache = new Map();

/**
 * 获取除Grid(包含分页器)之外的高度
 * @param size
 */
export function useSizeHeight(size: Size): number {
  const height = useMemo(() => {
    const {
      searchForm: { height: searchFormHeight },
      beforeSearch: { height: beforeSearchHeight },
      afterSearch: { height: afterSearchHeight },
      afterGrid: { height: afterGridHeight },
    } = size;
    const res =
      Math.ceil(searchFormHeight) +
      Math.ceil(beforeSearchHeight) +
      Math.ceil(afterSearchHeight) +
      Math.ceil(afterGridHeight);
    return res;
  }, [size]);

  return height;
}

function getCacheDataSourceImpl(dataSource: any[], dataSourceRef: any) {
  let res = dataSource;
  if (_isEqual(dataSourceRef.current, dataSource)) {
    res = dataSourceRef.current;
  } else {
    dataSourceRef.current = dataSource;
  }
  return res;
}

/**
 * 获取缓存的DataSource
 */
export function getCacheDataSource(
  direction: Direction,
  leftDataSourceRef: any,
  rightDataSourceRef: any,
  dataSource: any[],
) {
  let res = dataSource;
  if (direction === 'left') {
    res = getCacheDataSourceImpl(dataSource, leftDataSourceRef);
  } else {
    res = getCacheDataSourceImpl(dataSource, rightDataSourceRef);
  }
  return res;
}

function filterImpl(value: any = '', filterValue: string = '') {
  let tmepValue = value;
  if (!['string', 'number'].includes(typeof value) || typeof filterValue !== 'string') return false;
  if (typeof tmepValue === 'number') tmepValue = `${tmepValue}`;
  const filterValues = filterValue.split(/\s+/);
  return filterValues.some((filterValueItem) => {
    return tmepValue.includes(filterValueItem);
  });
}

/**
 * 过滤数据列表
 * @param dataSource
 * @param filterKey
 * @param filterKeyValue
 */
export function getFilterDateSource(dataSource: any[], filterKey: string = '', filterKeyValue: string = '') {
  if (!filterKeyValue) return dataSource;
  let currentValue = '';
  return dataSource.filter((item) => {
    if (!filterKey) {
      const find = Object.keys(item).find((keyItem) => {
        currentValue = item[keyItem] || '';
        return filterImpl(currentValue, filterKeyValue);
      });
      return find;
    }
    currentValue = item[filterKey] || '';
    return filterImpl(currentValue, filterKeyValue);
  });
}

/**
 * 根据是否禁用格式gird column配置
 * @param columns
 * @param disabled
 */
export function formatGridColumns(columns: any[], disabled: boolean, direction: Direction) {
  const cacheKey = `${disabled}:${direction}`;
  const cacheColumns = map[cacheKey];

  if (cacheColumns && cacheColumns === columns) {
    const cacheRes = cache.get(columns);
    if (cacheRes) {
      return cacheRes[cacheKey];
    }
  }

  const res = columns.map((item, index) => {
    const { fieldName, rowDrag } = item;
    const extra: any = {};

    // 首列配置拖拽
    if (index === 0 && !disabled) {
      extra.rowDrag = typeof rowDrag === 'undefined' ? true : rowDrag;
      // 配置拖拽时，tooltip的显示文本
      extra.rowDragText = (params: any, dragItemCount: number) => {
        if (dragItemCount > 1) {
          return `${tr('选择了')}${dragItemCount}${tr('行')}`;
        }
        return params.rowNode.data[fieldName];
      };
    }

    return {
      ...item,
      ...extra,
      sortable: false,
    };
  });

  map[cacheKey] = columns;
  const cacheRes = cache.get(columns);
  if (cacheRes) {
    cacheRes[cacheKey] = res;
  } else {
    cache.set(columns, { [cacheKey]: res });
  }

  return res;
}

/**
 * 获取数据的唯一key
 * @param data
 * @param rowKey
 */
export function getRowKey(data: any, rowKey: string | Function) {
  if (typeof rowKey === 'function') {
    return rowKey(data);
  }
  return data[rowKey];
}

/**
 * 获取行的自定义Class
 * @param overInfo
 * @param rowKey
 * @param params
 */
export function getDragOverRowClass(overInfo: any, rowKey: string | Function, dir: 'top' | 'bottom', params: any) {
  const { id, direction: _dir } = overInfo;
  const dataRowKey = getRowKey(params.node.data, rowKey);
  if (dataRowKey === id && dir === _dir) return true;
  return false;
}
